package com.lzx.hbh_system.service.Impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzx.hbh_system.bo.SysMenu;
import com.lzx.hbh_system.bo.SysRoleMenu;
import com.lzx.hbh_system.bo.filter.MenuFilter;
import com.lzx.hbh_system.dto.RouteDto;
import com.lzx.hbh_system.mapper.SysMenuMapper;
import com.lzx.hbh_system.mapper.SysRoleMenuMapper;
import com.lzx.hbh_system.service.MenuService;
import com.lzx.hbh_system.util.RedisUtils;
import com.lzx.hbh_system.util.SnowFlakeUtil;
import com.lzx.hbh_system.util.TurnDateToStringUtil;
import com.lzx.hbh_system.util.responseEntity.RespOutMsgHeader;
import com.lzx.hbh_system.util.responseEntity.ResponseView;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class MenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements MenuService{
    @Autowired
    private SysMenuMapper menuMapper;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private ModelMapper modelMapper;
    @Autowired
    private SysRoleMenuMapper roleMenuMapper;
    /**
     * 获取所有菜单信息列表
     * @param filter
     * @return
     */
    @Override
    public ResponseView getAllMenu(MenuFilter filter) {
        // 初始化返回视图
        ResponseView responseView = new ResponseView();
        List<Object> c = redisUtils.getList("menuList");
        List<SysMenu> menuList = new ArrayList<>();
        if (c != null && c.size() != 0){ // redis 不为空
            for (int i = 0; i < c.size(); i++) {
                SysMenu sysMenu = JSON.parseObject(c.get(i).toString(),SysMenu.class);
                menuList.add(sysMenu);
            }

        }else{ // 否则数据库中获取
            menuList = menuMapper.selectList(null);
            redisUtils.delete("menuList");
            redisUtils.lRightPushAll("menuList",menuList);
        }
        // 返回视图
        responseView.setMain(menuList.toArray());
        responseView.setRespOutMsgHeader(RespOutMsgHeader.success(menuList.size(),true,"查询成功！"));
        return responseView;
    }

    @Override
    public ResponseView getAllMenuDto() {
        // 初始化返回视图
        ResponseView responseView = new ResponseView();
        List<Object> c = redisUtils.getList("menuList");
        List<SysMenu> menuList = new ArrayList<>();
        if (c != null && c.size() != 0){ // redis 不为空
            for (int i = 0; i < c.size(); i++) {
                SysMenu sysMenu = JSON.parseObject(c.get(i).toString(),SysMenu.class);
                menuList.add(sysMenu);
            }

        }else{ // 否则数据库中获取
            menuList = menuMapper.selectList(null);
            redisUtils.delete("menuList");
            redisUtils.lRightPushAll("menuList",menuList);
        }
        List<RouteDto> routeDtos = getResultRouteList(menuList);
        // 返回视图
        responseView.setMain(routeDtos.toArray());
        responseView.setRespOutMsgHeader(RespOutMsgHeader.success(menuList.size(),true,"查询成功！"));
        return responseView;
    }

    /**
     *  查询该角色对应的菜单列表
     * @param filter
     * @return
     */
    @Override
    public ResponseView getMenuByFilter(MenuFilter filter) {
        // 初始化返回视图
        ResponseView responseView = new ResponseView();
        String roleCode = filter.getRoleCode();
        List<SysMenu> menuList = menuMapper.queryMenuByRoleCode(roleCode);
        //映射成RouteDto对象返回给前端
        List<RouteDto> routeDtos = getResultRouteList(menuList);
        // 避免出现多余子节点 再次过滤
        routeDtos = routeDtos.stream().filter(route->route.getChildren().size()!=0).collect(Collectors.toList());
        // 返回视图
        responseView.setMain(routeDtos.toArray());
        responseView.setRespOutMsgHeader(routeDtos.size()!=0 ? RespOutMsgHeader.success(routeDtos.size(),true,"查询成功！") : RespOutMsgHeader.success(0,false,"该角色尚未绑定路由菜单！"));
        return responseView;
    }

    @Override
    public ResponseView addOneMenuInfo(MenuFilter filter) {
        // 初始化返回视图
        ResponseView responseView = new ResponseView();
        // 基本校验
        if (filter.getMenuinfo() == null ){
            responseView.setRespOutMsgHeader(RespOutMsgHeader.error("菜单信息不能为空！"));
            return responseView;
        }
        if (filter.getMenuinfo().getIsSysFlag() == null ){
            responseView.setRespOutMsgHeader(RespOutMsgHeader.error("必须指定是否系统菜单"));
            return responseView;
        }
        // 删除redis存放的消息
        redisUtils.delete("menuList");
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("title",filter.getMenuinfo().getTitle());
        List<SysMenu> sysMenuList = menuMapper.selectList(queryWrapper);
        if ( sysMenuList.size() >= 1 ){
            responseView.setRespOutMsgHeader(RespOutMsgHeader.error("存在相同菜单名称，请勿重复！"));
            return responseView;
        }
        // 逻辑实现
        SysMenu menu = filter.getMenuinfo();
        String key = SnowFlakeUtil.getId(); // 生成雪花主键
        menu.setId(key);
        menu.setMenuCode(key); // 设定主键
        menu.setCreatTime(TurnDateToStringUtil.getDateTime());
        menu.setValiFlag("1"); // 默认有效
        menuMapper.insert(menu);
        // 返回消息
        responseView.setRespOutMsgHeader(RespOutMsgHeader.success("新增成功"));
        // 返回视图
        return responseView;
    }

    @Override
    public ResponseView getOneMenuInfo(MenuFilter filter) {
        // 初始化返回视图
        ResponseView responseView = new ResponseView();
        // 基本校验
        if (filter.getMenuCode() == null ){
            responseView.setRespOutMsgHeader(RespOutMsgHeader.error("菜单编号不能为空！"));
            return responseView;
        }
        // 逻辑实现
        // 获取菜单信息
        SysMenu menu = menuMapper.selectById(filter.getMenuCode());
        // 返回消息
        responseView.setMain(menu);
        responseView.setRespOutMsgHeader(RespOutMsgHeader.success("查询成功"));
        return responseView;
    }

    @Override
    public ResponseView modifyOneMenuInfo(MenuFilter filter) {
        // 初始化返回视图
        ResponseView responseView = new ResponseView();
        // 基本校验
        if (filter.getMenuinfo() == null ){
            responseView.setRespOutMsgHeader(RespOutMsgHeader.error("修改菜单的消息不能为空！"));
            return responseView;
        }
        // 删除redis存放的消息
        redisUtils.delete("menuList");
        // 逻辑实现
        SysMenu Omenu = filter.getMenuinfo();
        Omenu.setUpdateTime(TurnDateToStringUtil.getDateTime());
        menuMapper.updateById(Omenu);
        // 返回消息
        responseView.setRespOutMsgHeader(RespOutMsgHeader.success("修改成功"));
        return responseView;
    }

    @Override
    public ResponseView dropBatchMenuInfo(MenuFilter filter) {
        // 初始化返回视图
        ResponseView responseView = new ResponseView();
        // 基本校验
        if (filter.getMenuCodeList().size() == 0 ){
            responseView.setRespOutMsgHeader(RespOutMsgHeader.error("修改菜单的编号至少不能为空！"));
            return responseView;
        }
        // 删除redis存放的消息
        redisUtils.delete("menuList");
        // 逻辑实现
        List<String> MenuCodeList = filter.getMenuCodeList();
        MenuCodeList.forEach(item -> {
            SysMenu menu = menuMapper.selectById(item);
            if (menu.getIsSysFlag().equals("1")){
                // 系统菜单不能删除
                return;
            }
            menuMapper.deleteById(item);
            // 关联的角色菜单数据也删除
            QueryWrapper<SysRoleMenu> roleMenuQueryWrapper = new QueryWrapper<>();
            roleMenuQueryWrapper.eq("menu_code",item);
            roleMenuMapper.delete(roleMenuQueryWrapper);
        });
        // 返回消息
        responseView.setRespOutMsgHeader(RespOutMsgHeader.success("删除成功！（除系统菜单外）"));
        return responseView;
    }
    /**
     * 获取menuDto列表 转换函数
     * @param menuList
     * @return
     */
    public List<RouteDto> getRouteDtoList2(List<SysMenu> menuList){
        List<RouteDto> routeDtos = new ArrayList<>();
        menuList.forEach(menu->{
            RouteDto routeDto = new RouteDto();
            routeDto.setHidden(menu.getHidden());
            routeDto.setMainkey(menu.getParentCode());
            routeDto.setUrl(menu.getUrl());
            routeDto.setIcon(menu.getIcon());
            routeDto.setPath(menu.getMenuName());
            routeDto.setTitle(menu.getTitle());
            routeDto.setMenukey(menu.getMenuCode());
            routeDto.setChildren(new ArrayList<>());
            routeDtos.add(routeDto);
        });
       return routeDtos;
    }

    /**
     * 获取menuDto列表 主函数
     * @param menuList 原菜单对象列表
     * @return
     */
    public List<RouteDto> getResultRouteList(List<SysMenu> menuList){
        List<RouteDto> routeDtos = new ArrayList<>();
        List<SysMenu> MainMenuList  = menuList.stream().filter(menu -> Objects.equals(menu.getParentCode(), "0")).collect(Collectors.toList());
        menuList.removeAll(MainMenuList);
        List<SysMenu> SecondMenuList = menuList;
        List<RouteDto> MainrouteDtoList = getRouteDtoList2(MainMenuList);
        List<RouteDto> SecondrouteDtoList = getRouteDtoList2(SecondMenuList);
        MainrouteDtoList.forEach(Mainroute -> {
            RouteDto routeDto = modelMapper.map(Mainroute,RouteDto.class);
            routeDto.setChildren(SecondrouteDtoList.stream().filter(Secondroute -> Secondroute.getMainkey().equals(Mainroute.getMenukey())).collect(Collectors.toList()));
            routeDtos.add(routeDto);
        });
        return routeDtos;
    }
}
